#include <stdio.h>
#include <pthread.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include "shmem.h"
#include "msg_queue_peer.h"

// 共享内存数据结构（与MQTT代码完全一致）
union val_t {
    int b_val;   // 布尔值
    int i_val;   // 整数值
    float f_val; // 浮点值
};

// 设备节点结构（与MQTT代码的struct std_node完全一致）
struct std_node {
    int key;             // 唯一标识key（与点表对应）
    int type;            // 数据类型（1:布尔型, 2:整型, 3:浮点型）
    int dev_type;        // 设备归属（0:stm32, 1:modbus）
    union val_t old_val; // 旧值
    union val_t new_val; // 新值
    int ret;             // 状态标识（-1:失败, 0:成功）
};

// 全局变量
static struct shm_param para;
static int *total;              // 设备总数（从共享内存获取）
static struct std_node *node_arr; // 设备数组（与MQTT代码类型一致）
static int client_fd = -1;

// 配置参数（与MQTT代码共享内存关键参数统一）
#define PORT 8080
#define BUFFER_SIZE 1024
#define MAX_NODE 12        // 与MQTT代码保持一致（6个stm32+6个modbus）
#define SHM_KEY "shm_test" // 共享内存键与MQTT代码统一
#define MAX_NODE_SIZE (sizeof(int) + MAX_NODE * sizeof(struct std_node))  // 共享内存大小匹配

// 消息队列结构
struct msgbuf {
    long mtype;
    char mdata[BUFFER_SIZE];
};

// 消息队列处理线程
void *msg_queue_thread(void *arg) {
    struct msgbuf msg;
    while (1) {
        if (msg_queue_recv("device_topic", &msg, sizeof(msg), 0, 0) > 0) {
            printf("消息队列接收: 类型=%ld, 数据=%s\n", msg.mtype, msg.mdata);
            
            // 转发给客户端
            if (client_fd != -1) {
                send(client_fd, msg.mdata, strlen(msg.mdata), 0);
            }
        }
        sleep(1);
    }
    return NULL;
}

// 读取线程(共享内存)
void *output_thread(void *arg)
{
    int ret = -1;

    // 使用与MQTT代码相同的共享内存键初始化
    ret = shm_init(&para, SHM_KEY, MAX_NODE_SIZE);
    if (ret < 0)
    {
        printf("共享内存初始化失败\n");
        return NULL;
    }
    void *node_p = shm_getaddr(&para);
    if (node_p == NULL)
    {
        printf("获取共享内存地址失败\n");
        return NULL;
    }
    // 前4个字节存储实际的设备数目（与MQTT代码存储结构一致）
    total = (int *)node_p;
    // 后面空间存储数据点（使用与MQTT代码一致的struct std_node）
    node_arr = (struct std_node *)(node_p + sizeof(int));
    
    while (1)
    {
        // 每次循环都获取最新的设备数量（与MQTT代码保持同步）
        int n = *total;
        if (n > MAX_NODE) n = MAX_NODE; // 防止越界
        
        for (int i = 0; i < n; i++)
        {
            // 检测数据是否更新（与MQTT代码的更新检测逻辑一致）
            if (memcmp(&node_arr[i].old_val, &node_arr[i].new_val, sizeof(union val_t)) != 0)
            {
                node_arr[i].old_val = node_arr[i].new_val; // 更新旧值
                
                // 根据设备类型和key处理（与MQTT代码的设备分类逻辑匹配）
                const char *dev_type_str = (node_arr[i].dev_type == 0) ? "stm32" : "modbus";
                
                if (node_arr[i].key == 301) // 温度传感器
                {
                    printf("[%s] 温度: %.1f\n", dev_type_str, node_arr[i].new_val.f_val);
                }
                else if (node_arr[i].key == 302) // 湿度传感器
                {
                    printf("[%s] 湿度: %.1f\n", dev_type_str, node_arr[i].new_val.f_val);
                }
                else if (node_arr[i].key == 303) // 风扇开关
                {
                    printf("[%s] 风扇: %s\n", dev_type_str, 
                           node_arr[i].new_val.b_val ? "开启" : "关闭");
                }
                else if (node_arr[i].key == 304) // 窗帘
                {
                    printf("[%s] 窗帘: %s\n", dev_type_str, 
                           node_arr[i].new_val.b_val ? "打开" : "关闭");
                }
                else if (node_arr[i].key == 305) // 扫地机器人
                {
                    printf("[%s] 扫地机器人: %s\n", dev_type_str, 
                           node_arr[i].new_val.b_val ? "运行中" : "停止");
                }
                else if (node_arr[i].key == 306) // 其他设备
                {
                    printf("[%s] 设备%d: %d\n", dev_type_str, 
                           node_arr[i].key, node_arr[i].new_val.i_val);
                }
            }
        }
        sleep(1);
    }
    return NULL;
}

int main() {
    int server_fd;
    struct sockaddr_in addr;
    socklen_t addr_len = sizeof(addr);
    char buffer[BUFFER_SIZE];
    int n; // 用于接收数据长度
    
    // 创建消息队列线程
    pthread_t tid_msg, tid_output;
    if (pthread_create(&tid_msg, NULL, msg_queue_thread, NULL) != 0) {
        perror("创建消息队列线程失败");
        return -1;
    }
    pthread_detach(tid_msg);
    
    // 创建读取线程(共享内存)
    if (pthread_create(&tid_output, NULL, output_thread, NULL) != 0) {
        perror("创建共享内存读取线程失败");
        return -1;
    }
    pthread_detach(tid_output);
    
    // 创建TCP服务器
    if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) {
        perror("创建socket失败");
        return -1;
    }
    
    // 配置服务器地址
    addr.sin_family = AF_INET;
    addr.sin_addr.s_addr = INADDR_ANY;  // 监听所有IP
    addr.sin_port = htons(PORT);
    
    // 允许端口复用，避免程序退出后端口占用
    int opt = 1;
    setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(opt));
    
    // 绑定端口
    if (bind(server_fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {
        perror("绑定端口失败");
        close(server_fd);
        return -1;
    }
    
    // 监听连接
    if (listen(server_fd, 1) < 0) {
        perror("监听失败");
        close(server_fd);
        return -1;
    }
    
    printf("服务器启动，端口: %d\n", PORT);
    printf("等待客户端连接...\n");
    
    // 主循环
    while (1) {
        // 接受客户端连接
        if (client_fd == -1) {
            if ((client_fd = accept(server_fd, (struct sockaddr *)&addr, &addr_len)) < 0) {
                perror("接受连接失败");
                continue;
            }
            printf("客户端已连接: %s:%d\n", 
                   inet_ntoa(addr.sin_addr), ntohs(addr.sin_port));
        }
        else {
            // 接收客户端数据
            n = recv(client_fd, buffer, BUFFER_SIZE - 1, 0);
            if (n > 0) {
                buffer[n] = '\0';
                printf("收到客户端数据:\n%s\n", buffer);
                
                // 解析多行指令
                char *line = strtok(buffer, "\n");
                while (line != NULL) {
                    // 解析单行格式: key:value
                    char *colon = strchr(line, ':');
                    if (colon != NULL) {
                        *colon = '\0';  // 分割key和value
                        int key = atoi(line);
                        char *value_str = colon + 1;
                        
                        // 根据设备key处理不同类型的值（与MQTT代码数据类型匹配）
                        if (key >= 301 && key <= 306) {
                            // 查找对应的设备
                            int found = 0;
                            if (total != NULL && node_arr != NULL) {
                                int dev_count = *total;
                                if (dev_count > MAX_NODE) dev_count = MAX_NODE;
                                
                                for (int i = 0; i < dev_count; i++) {
                                    if (node_arr[i].key == key) {
                                        // 与MQTT代码保持相同的数据类型处理逻辑
                                        if (node_arr[i].type == 3) {  // 浮点型
                                            node_arr[i].new_val.f_val = atof(value_str);
                                        } else {  // 布尔/整型（type=1/2）
                                            node_arr[i].new_val.i_val = atoi(value_str);
                                        }
                                        // 同步更新状态标识（与MQTT代码一致）
                                        node_arr[i].ret = 0;
                                        printf("已更新设备 %d (类型:%s) 的值为: %s\n", 
                                               key, 
                                               (node_arr[i].dev_type == 0) ? "stm32" : "modbus",
                                               value_str);
                                        found = 1;
                                        break;
                                    }
                                }
                            }
                            if (!found) {
                                printf("未找到设备 %d\n", key);
                            }
                        } else {
                            printf("无效的设备ID: %d（有效范围301-306）\n", key);
                        }
                    } else {
                        printf("无效的指令格式: %s (正确格式: key:value)\n", line);
                    }
                    
                    line = strtok(NULL, "\n");  // 解析下一行
                }
            }
            // 客户端断开连接
            else if (n == 0) {
                printf("客户端断开连接\n");
                close(client_fd);
                client_fd = -1;
            }
            // 接收错误
            else {
                perror("接收数据错误");
                close(client_fd);
                client_fd = -1;
            }
        }
        
        usleep(100000);  // 短暂休眠，降低CPU占用
    }
    
    // 清理资源
    close(server_fd);
    shm_close(&para);
    return 0;
}
